home *** CD-ROM | disk | FTP | other *** search
- /* net.c
- network and socket maintenance procedures */
-
- /*---------------------------------------------------------------*/
- /* Xgopher version 1.3 08 April 1993 */
- /* version 1.2 20 November 1992 */
- /* version 1.1 20 April 1992 */
- /* version 1.0 04 March 1992 */
- /* X window system client for the University of Minnesota */
- /* Internet Gopher System. */
- /* Allan Tuchman, University of Illinois at Urbana-Champaign */
- /* Computing and Communications Services Office */
- /* Copyright 1992, 1993 by */
- /* the Board of Trustees of the University of Illinois */
- /* Permission is granted to freely copy and redistribute this */
- /* software with the copyright notice intact. */
- /*---------------------------------------------------------------*/
-
-
- /* The header files here need to be checked and corrected on almost
- a per-machine basis. */
-
- #include <stdio.h>
-
- #ifndef IS_BSD
- #include <stdlib.h>
- #endif
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
-
- #ifndef IS_A_HPUX
- #include <arpa/inet.h>
- #endif
-
- #include <netdb.h>
- #include <signal.h>
-
- #include <ctype.h>
- #include <errno.h>
- #include <time.h>
-
- #include <sys/param.h>
- #include "gopher.h"
- #include "globals.h"
- #include "osdep.h"
-
-
- /* <netinet/in.h> should define INADDR_NONE for a failed return
- from inet_addr(). Just in case it is not defined on some machine
- it is defined here to -1. Most machines return a -1. If this
- assumption is false, we're lost anyway and a hand change is needed. */
-
- #ifndef INADDR_NONE
- #define INADDR_NONE -1
- #endif
-
-
- /* connectToSocket
- performs a connection to socket 'port' on host 'host'.
-
- Errors:
- -2 get host failed
- -3 socket call failed
- -4 connect call failed
- */
-
- static struct sockaddr_in server;
- struct hostent *hostPtr;
-
- /* OS dependencies:
-
- . gethostname(char *, int) is a Unix kernel call to return the
- address of a string containing the local host name.
- . MAXHOSTNAMELEN is set in <sys/param.h> to be the maximum host name
- size. This is often 64 for BSD Unix.
-
- */
-
- int
- connectToSocket(host, port)
- char *host;
- int port;
- {
- /* Host can be a hostname or ip-address.
- If 'host' is null, the local host is assumed. */
-
- int iSock = 0;
- char hostName[MAXHOSTNAMELEN];
-
- LOG(logFP, "Connecting to \'%s\' at port %d\n", host, port);
- if (host == '\0') {
- gethostname(hostName, MAXHOSTNAMELEN);
- host = hostName;
- }
-
- if ((server.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
- if ((hostPtr = gethostbyname(host)) != NULL) {
- bzero((char *) &server, sizeof(server));
- bcopy(hostPtr->h_addr, (char *) &server.sin_addr,
- hostPtr->h_length);
- server.sin_family = hostPtr->h_addrtype;
- } else {
- return (-2);
- }
- } else {
- server.sin_family = AF_INET;
- }
-
- server.sin_port = (unsigned short) htons(port);
-
- /* in the socket call, should AF_INET be replaced with
- server.sin_family? */
-
- if ((iSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return (-3);
-
- setsockopt(iSock, SOL_SOCKET, ~SO_LINGER, 0, 0);
- setsockopt(iSock, SOL_SOCKET, SO_REUSEADDR, 0, 0);
- setsockopt(iSock, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
-
- if (connect(iSock, (struct sockaddr *) &server, sizeof(server)) < 0) {
- close(iSock);
- return (-4);
- }
- return(iSock);
- }
-
-
- /* networkError
- Checks the return value from connectToSoocket and report any error */
-
- void
- networkError(gfd, host, port)
- int gfd;
- char *host;
- {
- char errorString[MESSAGE_STRING_LEN];
- #define NET_ERROR_MESSAGE "Cannot establish a network connection"
-
- switch(gfd) {
- case -4:
- if (port != 0)
- (void) sprintf(errorString,
- "%s\n(could not connect to remote computer \'%s\' at port %d)",
- NET_ERROR_MESSAGE, host, port);
- else
- (void) sprintf(errorString,
- "%s\n(could not connect to remote computer \'%s\')",
- NET_ERROR_MESSAGE, host);
- break;
- case -3:
- (void) sprintf(errorString,
- "%s\n(because socket failed)",
- NET_ERROR_MESSAGE);
- break;
- case -2:
- (void) sprintf(errorString,
- "%s\n(could not identify the remote host computer \'%s\')",
- NET_ERROR_MESSAGE, host);
- break;
- }
-
- if (gfd < 0) {
- showError(errorString);
- }
- }
-
- /* ----- */
-
- /* Read "n" bytes from a descriptor.
- * Use in place of read() when fd is a stream socket
- *
- * Returns the number of total bytes read.
- */
-
- int readn(fd, ptr, nbytes)
- int fd;
- char *ptr;
- int nbytes;
- {
- int nleft, nread;
-
- nleft = nbytes;
- while (nleft > 0) {
- nread = read(fd, ptr, nleft);
- if (nread < 0)
- return(nread); /* error, return <0 */
- else if (nread == 0) /* EOF */
- break;
-
- nleft -= nread;
- ptr += nread;
- }
- return(nbytes - nleft); /* return >= 0) */
- }
-
-
-
- /*
- * Write "n" bytes to a descriptor.
- * Use in place of write() when fd is a stream socket
- *
- * We return the number of bytes written
- */
-
- int writen(fd, ptr, nbytes)
- int fd;
- char *ptr;
- int nbytes;
- {
- int nleft, nwritten;
-
- nleft = nbytes;
- while(nleft > 0) {
- nwritten = write(fd, ptr, nleft);
- if (nwritten <= 0)
- return(nwritten); /* error */
-
- nleft -= nwritten;
- ptr += nwritten;
- }
- return(nbytes - nleft);
- }
-
-
- /*
- * Writestring uses the writen and strlen calls to write a
- * string to the file descriptor fd. If the write fails
- * a -1 is returned. Otherwise zero is returned.
- */
-
- int writeString(fd, stringptr)
- int fd;
- char *stringptr;
- {
- int length;
-
- length = strlen(stringptr);
- if (writen(fd, stringptr, length) != length)
- return(-1);
- else
- return(0);
- }
-
-
- /*
- * Read a line from a descriptor. Read the line one byte at a time,
- * looking for the newline. We store the newline in the buffer,
- * then follow it with a null (the same as fgets(3)).
- * We return the number of characters up to, but not including,
- * the null (the same as strlen(3))
- */
-
- int readLine(fd, ptr, maxlen)
- int fd;
- char *ptr;
- int maxlen;
- {
- int n;
- int rc;
- char c;
-
- for (n=1; n < maxlen; n++) {
- if ( (rc = read(fd, &c, 1)) == 1) {
- *ptr++ = c;
- if (c == '\n')
- break;
- }
- else if (rc == 0) {
- if (n == 1)
- return(0); /* EOF, no data read */
- else
- break; /* EOF, some data was read */
- }
- else
- return(-1); /* error */
- }
-
- *ptr = 0; /* Tack a NULL on the end */
- return(n);
- }
-
- /*
- * Readfield reads data up to a tab, (like readline above)
- */
-
- int readField(fd, ptr, maxlen)
- int fd;
- char *ptr;
- int maxlen;
- {
- int n;
- int rc;
- char c;
-
- for (n=1; n < maxlen; n++) {
- if ( (rc = read(fd, &c, 1)) == 1) {
- *ptr++ = c;
- if (c == '\t') {
- *(ptr - 1) = '\0';
- break;
- }
- }
- else if (rc == 0) {
- if (n == 1)
- return(0); /* EOF, no data read */
- else
- break; /* EOF, some data was read */
- }
- else
- return(-1); /* error */
- }
-
- *ptr = 0; /* Tack a NULL on the end */
- return(n);
- }
-
-
- /*
- * readDelim reads data up to a delimiter or EOL (similar to readfield above)
- */
-
- int readDelim(fd, ptr, maxlen, delim)
- int fd;
- char *ptr;
- int maxlen;
- char delim;
- {
- int n;
- int rc;
- char c;
-
- for (n=1; n < maxlen; n++) {
- if ( (rc = read(fd, &c, 1)) == 1) {
- *ptr++ = c;
- if (c == delim || c == '\n') {
- *(ptr - 1) = '\0';
- break;
- }
- }
- else if (rc == 0) {
- if (n == 1)
- return(0); /* EOF, no data read */
- else
- break; /* EOF, some data was read */
- }
- else
- return(-1); /* error */
- }
-
- *ptr = 0; /* Tack a NULL on the end */
- return(n);
- }
-
-
- #ifdef NOT_NEEDED
- int
- sreadword(input, output, maxlen)
- char *input;
- char *output;
- int maxlen;
- {
- int n;
- char c;
-
- for (n=0; n < maxlen; n++) {
- c = *input++;
- *output++ = c;
- if (isspace(c)) {
- *(output - 1) = '\0';
- break;
- }
-
- if (c == NULL) {
- break;
- }
- }
-
- *output = '\0'; /* Tack a NULL on the end */
- return(n);
- }
- #endif /* NOT_NEEDED */
-
- /*
- * zapCRLF removes all carriage returns and linefeeds from a C-string.
- */
-
- void
- zapCRLF(inputline)
- char *inputline;
- {
- char *cp;
-
- cp = index(inputline, '\r'); /* Zap CR-LF */
- if (cp != NULL)
- *cp = '\0';
- else {
- cp = index(inputline, '\n');
- if (cp != NULL)
- *cp = '\0';
- }
- }
-